// @Description
// @Author  xiaoyang
// @Date  2023/4/27 3:31 下午

package middles

import (
	"github.com/gin-gonic/gin"
	"github.com/go-playground/locales/en"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"golang-manage-admin/lib"
	"gopkg.in/go-playground/validator.v9"
	enTranslations "gopkg.in/go-playground/validator.v9/translations/en"
	zhTranslations "gopkg.in/go-playground/validator.v9/translations/zh"
	"reflect"
	"regexp"
)

// 自定义验证器
type Validation struct {
	Tag  string         // 验证标签
	Func validator.Func // 自定义方法
}

// 自定义翻译器
type Translation struct {
	Tag           string                             // 是标签名称，例如 required、len、min 等；
	Trans         ut.Translator                      // 翻译器对象
	RegisterFn    validator.RegisterTranslationsFunc // 是一个回调函数，用于注册翻译模板
	TranslationFn validator.TranslationFunc
}

/**
 *  @Author yang
 *  @Description 注册自定义的验证方法
**/
func registerValidations(val *validator.Validate, validations []Validation) {
	// 遍历注册
	for _, value := range validations {
		val.RegisterValidation(value.Tag, value.Func)
	}
}

func registerTranslations(val *validator.Validate, translations []Translation) {
	// 遍历注册
	for _, value := range translations {
		val.RegisterTranslation(value.Tag, value.Trans, value.RegisterFn, value.TranslationFn)
	}
}

// SetupValidator
// @Description:  初始化验证器对象和翻译器对象，注册自定义验证方法
// @Author yang 2025-11-26 17:40:00
// @Return gin.HandlerFunc
func SetupValidator() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 初始化验证器和翻译器对象
		en := en.New()
		zh := zh.New()
		uni := ut.New(zh, zh, en)
		val := validator.New()

		//根据参数取翻译器实例
		var trans ut.Translator
		// 根据请求头中的 Accept-Language 属性来设置语言环境及对应的翻译器
		switch c.GetHeader("Accept-Language") {
		case "zh": // China
			trans, _ = uni.GetTranslator("zh")
		case "en": // English
			trans, _ = uni.GetTranslator("en")
		default: // 默认 China
			trans, _ = uni.GetTranslator("zh")
		}

		// 注册自定义验证方法
		validations := setValidationsData()
		registerValidations(val, validations)

		// 注册自定义翻译器
		translations := setTranslationsData(trans)
		registerTranslations(val, translations)

		// 根据语言环境注册翻译器、标签名称回调函数和默认翻译
		switch trans.Locale() {
		case "en":
			enTranslations.RegisterDefaultTranslations(val, trans)
			val.RegisterTagNameFunc(func(fld reflect.StructField) string {
				return fld.Tag.Get("en_comment")
			})
		default:
			zhTranslations.RegisterDefaultTranslations(val, trans)
			val.RegisterTagNameFunc(func(fld reflect.StructField) string {
				return fld.Tag.Get("comment")
			})
		}

		// 将验证器和翻译器对象存储到上下文对象中
		c.Set(lib.ValidatorKey, val)    // 存储验证器对象
		c.Set(lib.TranslatorKey, trans) // 存储翻译器对象
		c.Next()                        // 继续执行后续的中间件或者路由处理函数
	}
}

/**
 *  @Author yang
 *  @Description 初始化自定义验证器
**/
func setValidationsData() []Validation {
	return []Validation{
		{ // 签名验证
			Tag: "mobile_cn",
			Func: func(fl validator.FieldLevel) bool {
				mobile := fl.Field().String()
				regexp := regexp.MustCompile(`^1[3456789]\d{9}$`)
				return regexp.MatchString(mobile)
			},
		},
	}
}

/**
 *  @Author yang
 *  @Description 初始化自定义翻译器
**/
func setTranslationsData(trans ut.Translator) []Translation {
	return []Translation{
		{
			Tag:   "mobile_cn",
			Trans: trans,
			RegisterFn: func(ut ut.Translator) error {
				return ut.Add("mobile_cn", "{0} 不是有效的中国大陆手机号码！", true)
			},
			TranslationFn: func(ut ut.Translator, fe validator.FieldError) string {
				t, _ := ut.T(fe.Tag(), fe.Field())
				return t
			},
		},
	}
}
